function str2num(type, str) {
    if (type.search('int')!==-1) {
        return parseInt(str);
    } else if (type.search('float')!==-1) {
        return parseFloat(str);
    }
    return str;
}

function parseCsv(str) {
    let rows = str.split('\r\n');
    if (rows.length==1) {
        rows = str.split('\n');
    }
    if (rows.length==1) {
        rows = str.split('\r');
    }
    if (rows.length > 3) {
        let title = rows[1].split('\t');
        let type = rows[2].split('\t');
        let key1 = null;
        let key2 = null;
        for (let i = 0; i < title.length; i++) {
            if (title[i].charAt(0)=='*') {
                title[i] = title[i].substr(1);
                if (key1===null) {
                    key1 = i;
                } else if (key2===null) {
                    key2 = i;
                    break;
                }
            }
        }
        let table = new Map();
        for (let i = 3; i < rows.length; i++) {
            if (rows[i].length<2) {
                continue;
            }
            let row = rows[i].split('\t');
            let r = {};
            let key = key2===null?row[key1]:`${row[key1]}@${row[key2]}`;
            if (key2===null) {
                key = str2num(type[key1], key);
            }
            for (let j = 0; j < row.length; j++) {
                if (type[j].charAt(type[j].length-1)==':') {
                    row[j] = row[j].split('|');
                    for (let k = 0; k < row[j].length; k++) {
                        row[j][k] = row[j][k].split(':');
                        for (let l = 0; l < row[j][k].length; l++) {
                            row[j][k][l] = str2num(type[j], row[j][k][l]);
                        }
                    }
                } else if (type[j].charAt(type[j].length-1)=='|') {
                    row[j] = row[j].split('|');
                    for (let k = 0; k < row[j].length; k++) {
                        row[j][k] = str2num(type[j], row[j][k]);
                    }
                } else {
                    row[j] = str2num(type[j], row[j]);
                }
                r[title[j]] = row[j];
            }
            table.set(key, r);
        }
        table.find = function (key1, key2=null) {
            if (key2==null) {
                return this.get(key1);
            } else {
                return this.get(`${key1}@${key2}`);
            }
        }
        return table;
    }
    return null;
}

function parseCsv2Array(str) {
    let rows = str.split('\r\n');
    if (rows.length==1) {
        rows = str.split('\n');
    }
    if (rows.length==1) {
        rows = str.split('\r');
    }
    if (rows.length > 3) {
        let title = rows[1].split('\t');
        let type = rows[2].split('\t');
        let table = [];
        for (let i = 0; i < title.length; i++) {
            if (title[i].charAt(0)=='*') {
                title[i] = title[i].substr(1);
            }
        }
        for (let i = 3; i < rows.length; i++) {
            if (rows[i].length<2) {
                continue;
            }
            let row = rows[i].split('\t');
            let r = {};
            for (let j = 0; j < row.length; j++) {
                if (type[j].charAt(type[j].length-1)==':') {
                    row[j] = row[j].split('|');
                    for (let k = 0; k < row[j].length; k++) {
                        row[j][k] = row[j][k].split(':');
                        for (let l = 0; l < row[j][k].length; l++) {
                            row[j][k][l] = str2num(type[j], row[j][k][l]);
                        }
                    }
                } else if (type[j].charAt(type[j].length-1)=='|') {
                    row[j] = row[j].split('|');
                    for (let k = 0; k < row[j].length; k++) {
                        row[j][k] = str2num(type[j], row[j][k]);
                    }
                } else {
                    row[j] = str2num(type[j], row[j]);
                }
                r[title[j]] = row[j];
            }
            table.push(r);
        }
        return table;
    }
    return null;
}

module.exports.parseCsv = parseCsv;
module.exports.parseCsv2Array = parseCsv2Array;